/*
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup OH_NativeXComponent Native XComponent
 * @{
 *
 * @brief 描述ArkUI XComponent持有的surface和触摸事件，该事件可用于EGL/OpenGLES和媒体数据输入，并显示在ArkUI XComponent上。
 *
 * @since 8
 * @version 1.0
 */

/**
 * @file native_interface_xcomponent.h
 *
 * @brief 声明用于访问Native XComponent的API。
 *
 * @since 8
 * @version 1.0
 */

#ifndef _NATIVE_INTERFACE_XCOMPONENT_H_
#define _NATIVE_INTERFACE_XCOMPONENT_H_

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 枚举API访问状态。
 *
 * @since 8
 * @version 1.0
 */
enum {
    /** 成功结果。 */
    OH_NATIVEXCOMPONENT_RESULT_SUCCESS = 0,
    /** 失败结果。 */
    OH_NATIVEXCOMPONENT_RESULT_FAILED = -1,
    /** 无效参数。 */
    OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER = -2,
};

/**
 * @brief 触摸事件类型。
 * @since 8
 */
typedef enum {
    /** 手指按下时触发触摸事件。 */
    OH_NATIVEXCOMPONENT_DOWN = 0,
    /** 手指抬起时触发触摸事件。 */
    OH_NATIVEXCOMPONENT_UP,
    /** 手指按下状态下在屏幕上移动时触发触摸事件。 */
    OH_NATIVEXCOMPONENT_MOVE,
    /** 触摸事件取消时触发事件。 */
    OH_NATIVEXCOMPONENT_CANCEL,
    /** 无效的触摸类型。 */
    OH_NATIVEXCOMPONENT_UNKNOWN,
} OH_NativeXComponent_TouchEventType;

/**
 * @brief 鼠标事件动作.
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** 无效鼠标事件 。*/
    OH_NATIVEXCOMPONENT_MOUSE_NONE = 0,
    /** 鼠标按键按下时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_MOUSE_PRESS,
    /** 鼠标按键松开时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_MOUSE_RELEASE,
    /** 鼠标在屏幕上移动时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_MOUSE_MOVE,
} OH_NativeXComponent_MouseEventAction;

/**
 * @brief 鼠标事件按键。
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** 鼠标无按键操作时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_NONE_BUTTON = 0,
    /** 按下鼠标左键时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_LEFT_BUTTON = 0x01,
    /** 按下鼠标右键时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_RIGHT_BUTTON = 0x02,
    /** 按下鼠标中键时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_MIDDLE_BUTTON = 0x04,
    /** 按下鼠标左侧后退键时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_BACK_BUTTON = 0x08,
    /** 按下鼠标左侧前进键时触发鼠标事件。 */
    OH_NATIVEXCOMPONENT_FORWARD_BUTTON = 0x10,
} OH_NativeXComponent_MouseEventButton;

#define OH_NATIVE_XCOMPONENT_OBJ ("__NATIVE_XCOMPONENT_OBJ__")
const uint32_t OH_XCOMPONENT_ID_LEN_MAX = 128;
const uint32_t OH_MAX_TOUCH_POINTS_NUMBER = 10;

typedef struct {
    /** 手指的唯一标识符。 */
    int32_t id = 0;
    /** 触摸点相对于屏幕左边缘的x坐标。 */
    float screenX = 0.0;
    /** 触摸点相对于屏幕上边缘的y坐标。 */
    float screenY = 0.0;
    /** 触摸点相对于XComponent组件左边缘的x坐标。 */
    float x = 0.0;
    /** 触摸点相对于XComponent组件上边缘的y坐标。 */
    float y = 0.0;
    /** 触摸事件的触摸类型。 */
    OH_NativeXComponent_TouchEventType type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
    /** 指垫和屏幕之间的接触面积。 */
    double size = 0.0;
    /** 当前触摸事件的压力。 */
    float force = 0.0;
    /** 当前触摸事件的时间戳。 */
    long long timeStamp = 0;
    /** 当前点是否被按下。 */
    bool isPressed = false;
} OH_NativeXComponent_TouchPoint;

/**
 * @brief 触摸事件。
 *
 * @since 8
 * @version 1.0
 */
typedef struct {
    /** 手指的唯一标识符。 */
    int32_t id = 0;
    /** 触摸点相对于屏幕左边缘的x坐标。 */
    float screenX = 0.0;
    /** 触摸点相对于屏幕上边缘的y坐标。 */
    float screenY = 0.0;
    /** 触摸点相对于XComponent组件左边缘的x坐标。 */
    float x = 0.0;
    /** 触摸点相对于XComponent组件上边缘的y坐标。 */
    float y = 0.0;
    /** 触摸事件的触摸类型。 */
    OH_NativeXComponent_TouchEventType type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
    /** 指垫和屏幕之间的接触面积。 */
    double size = 0.0;
    /** 当前触摸事件的压力。 */
    float force = 0.0;
    /** 产生当前触摸事件的设备的ID。 */
    int64_t deviceId = 0;
    /** 当前触摸事件的时间戳。 */
    long long timeStamp = 0;
    /** 当前触摸点的数组。 */
    OH_NativeXComponent_TouchPoint touchPoints[OH_MAX_TOUCH_POINTS_NUMBER];
    /** 当前接触点的数量。 */
    uint32_t numPoints = 0;
} OH_NativeXComponent_TouchEvent;

/**
 * @brief 鼠标事件。
 *
 * @since 9
 * @version 1.0
 */
typedef struct {
    /** 点击触点相对于当前组件左上角的x轴坐标。 */
    float x;
    /** 点击触点相对于当前组件左上角的y轴坐标。 */
    float y;
    /** 点击触点相对于屏幕左上角的x轴坐标。 */
    float screenX;
    /** 点击触点相对于屏幕左上角的y轴坐标。 */
    float screenY;
    /** 当前鼠标事件的时间戳 */
    int64_t timestamp;
    /** 当前鼠标事件动作。 */
    OH_NativeXComponent_MouseEventAction action;
    /** 鼠标事件按键 */
    OH_NativeXComponent_MouseEventButton button;
} OH_NativeXComponent_MouseEvent;

/**
 * @brief 提供封装的OH_NativeXComponent实例。
 *
 * @since 8
 * @version 1.0
 */
typedef struct OH_NativeXComponent OH_NativeXComponent;

/**
 * @brief 注册surface生命周期和触摸事件回调。
 *
 * @since 8
 * @version 1.0
 */
typedef struct OH_NativeXComponent_Callback {
    /** 创建surface时调用。 */
    void (*OnSurfaceCreated)(OH_NativeXComponent* component, void* window);
    /** 当surface改变时调用。 */
    void (*OnSurfaceChanged)(OH_NativeXComponent* component, void* window);
    /** 当surface被破坏时调用。 */
    void (*OnSurfaceDestroyed)(OH_NativeXComponent* component, void* window);
    /** 当触摸事件被触发时调用。 */
    void (*DispatchTouchEvent)(OH_NativeXComponent* component, void* window);
} OH_NativeXComponent_Callback;

/**
 * @brief 注册鼠标事件的回调。
 *
 * @since 9
 * @version 1.0
 */
typedef struct OH_NativeXComponent_MouseEvent_Callback {
    /** 当鼠标事件被触发时调用。 */
    void (*DispatchMouseEvent)(OH_NativeXComponent* component, void* window);
    /** 当悬停事件被触发时调用。 */
    void (*DispatchHoverEvent)(OH_NativeXComponent* component, bool isHover);
} OH_NativeXComponent_MouseEvent_Callback;

/**
 * @brief 获取ArkUI XComponent的id。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param id 指示用于保存此OH_NativeXComponent实例的ID的字符缓冲区。
 *        请注意，空终止符将附加到字符缓冲区，因此字符缓冲区的大小应至少比真实id长度大一个单位。
 *        建议字符缓冲区的大小为[OH_XCOMPONENT_ID_LEN_MAX + 1]。
 * @param size 指示指向id长度的指针。
 * @return 返回执行的状态代码。
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentId(OH_NativeXComponent* component, char* id, uint64_t* size);

/**
 * @brief 获取ArkUI XComponent持有的surface的大小。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param window 表示NativeWindow句柄。
 * @param width 指示指向当前surface宽度的指针。
 * @param height 指示指向当前surface高度的指针。
 * @return 返回执行的状态代码。
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentSize(
    OH_NativeXComponent* component, const void* window, uint64_t* width, uint64_t* height);

/**
 * @brief 获取ArkUI XComponent组件相对屏幕左上顶点的偏移量。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param window 表示NativeWindow句柄。
 * @param x 指示指向当前surface的x坐标的指针。
 * @param y 指示指向当前surface的y坐标的指针。
 * @return 返回执行的状态代码。
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentOffset(
    OH_NativeXComponent* component, const void* window, double* x, double* y);

/**
 * @brief 获取ArkUI XComponent调度的触摸事件。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param window 表示NativeWindow句柄。
 * @param touchEvent 指示指向当前触摸事件的指针。
 * @return 返回执行的状态代码。
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetTouchEvent(
    OH_NativeXComponent* component, const void* window, OH_NativeXComponent_TouchEvent* touchEvent);

/**
 * @brief 获取ArkUI XComponent调度的鼠标事件
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param window 表示NativeWindow句柄
 * @param mouseEvent 指示指向当前鼠标事件的指针。
 * @return 返回执行的状态代码。
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetMouseEvent(
    OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent);

/**
 * @brief 为此OH_NativeXComponent实例注册回调。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param callback 指示指向surface生命周期和触摸事件回调的指针。
 * @return 返回执行的状态代码。
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_RegisterCallback(OH_NativeXComponent* component, OH_NativeXComponent_Callback* callback);

/**
 * @brief 为此OH_NativeXComponent实例注册鼠标事件回调。
 *
 * @param component 表示指向OH_NativeXComponent实例的指针。
 * @param callback 指示指向鼠标事件回调的指针。
 * @return 返回执行的状态代码。
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_RegisterMouseEventCallback(
    OH_NativeXComponent* component, OH_NativeXComponent_MouseEvent_Callback* callback);
#ifdef __cplusplus
};
#endif
#endif // _NATIVE_INTERFACE_XCOMPONENT_H_
